#pragma once

#include <any>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <vector>

#include "zrpc/base/timer.h"
#include "zrpc/http/http_context.h"
#include "zrpc/net/tcp_client.h"
#include "zrpc/net/tcp_connection.h"
namespace zrpc {
class HttpClient {
 public:
  typedef std::function<void(
      const std::shared_ptr<TcpConnection> &, HttpResponse &,
      const std::weak_ptr<TcpConnection> &, const std::any &)>
      HttpCallBack;
  HttpClient(EventLoop *loop);

  void OnConnection(const std::shared_ptr<TcpConnection> &conn);

  void OnMessage(const std::shared_ptr<TcpConnection> &conn, Buffer *buffer);

  void PostUrl(const char *ip, int16_t port, const std::string &url,
               const std::string &body, const std::string &host,
               const std::string &type,
               const std::shared_ptr<TcpConnection> &conn,
               const std::any &context, HttpCallBack &&callback);

  void GetUrl(const char *ip, int16_t port, const std::string &url,
              const std::string &host,
              const std::shared_ptr<TcpConnection> &conn,
              const std::any &context, HttpCallBack &&callback);

  void HttpClientTimerCallback(const int64_t index);

 private:
  EventLoop *loop_;
  std::unordered_map<int64_t, std::shared_ptr<Timer>> timers_;
  std::unordered_map<int64_t, std::shared_ptr<TcpClient>> tcp_clients_;
  std::unordered_map<int64_t, std::weak_ptr<TcpConnection>> tcp_conns_;
  std::unordered_map<int64_t, HttpCallBack> http_callbacks_;
  std::unordered_map<int64_t, std::any> any_callbacks_;
  const static int32_t kHeart = 10;
  const static int32_t kTimer = 60;
  int64_t index_;
};
}  // namespace zrpc
